package cc.rengu.igas.share.core.service.trans;

import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.enums.RespCodeEnum;
import cc.rengu.igas.share.common.enums.UserPayAuthTypeEnum;
import cc.rengu.igas.share.core.model.UpqcPayerInfo;
import cc.rengu.igas.share.core.model.UpqcTransAddnInfo;
import cc.rengu.igas.share.core.realize.UserService;
import cc.rengu.igas.share.core.realize.impl.UserServiceImpl;
import cc.rengu.igas.share.core.service.base.NoticeService;
import cc.rengu.igas.share.core.service.channel.upqc.C2bAddDealNoticeService;
import cc.rengu.igas.share.facade.request.UpqcC2bAddDealRequest;
import cc.rengu.igas.share.facade.response.UpqcC2bAddDealResponse;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.model.TxnInfo;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.TxnInfoService;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.service.realize.impl.TxnInfoServiceImpl;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;

import java.util.List;
import java.util.Optional;

/**
 * 银联二维码发起附加处理服务
 * BizStatus：
 * 01-业务处理中
 * 40-授权未完成【待密码认证】
 * 41-授权已完成【密码验证完成】
 * <p>
 * 订单表字段：
 * remark1：预授权状态
 * remark2：二维码类型
 * remark3：付款人信息
 * front_seq_num前端流水号：付款凭证号
 */
public class UpqcC2BAddDealService extends NoticeService implements TransCustomImpl {

    @Override
    protected Object bizBeforeCust() throws Exception {
        UpqcC2bAddDealRequest upqcC2bAddDealRequest = new UpqcC2bAddDealRequest();
        ConvertUtil.convertOutput(upqcC2bAddDealRequest);
        return upqcC2bAddDealRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        UpqcC2bAddDealRequest upqcC2bAddDealRequest = (UpqcC2bAddDealRequest) request;
        String instId = upqcC2bAddDealRequest.getHeader().getInstId();
        String payInfo = upqcC2bAddDealRequest.getPayerInfoStr();
        UpqcPayerInfo payerInfo = (UpqcPayerInfo) convertKvStr2Bean(payInfo.substring(1, payInfo.length() - 1), UpqcPayerInfo.class);
        rglog.debug("payerInfo:<{}>", JSON.toJSONString(payerInfo));

        /* 根据订单号获取原支付交易订单信息 */
        String deBase64Str = new String(Base64.decodeBase64(upqcC2bAddDealRequest.getReqReserved()));
        JSONObject reqResJson = JSON.parseObject(deBase64Str);
        OrderService orderService = new OrderServiceImpl();
        OrderInfo orderInfo = orderService.selectOrderInfoBySysSeqNum(instId, reqResJson.getString("flowNo"));
        if (null == orderInfo) {
            rglog.debug("银联通知需要认证接口，查询用户订单表异常, 二维码编号|订单编号{}", upqcC2bAddDealRequest.getReqReserved());
            throw new BizException(RespCodeEnum.ORDER_NOT_EXIST.getRespCode(), RespCodeEnum.ORDER_NOT_EXIST.getRespDesc());
        }
        UserOrderInfo userOrderInfo = orderInfo.getUserOrderInfo();

        // 更新业务状态，40-授权未完成【待密码认证】
        userOrderInfo.setBizStatus(BizStatusEnum.AUTH_INCOMPLETE.getStatus());
        // 付款凭证号
        userOrderInfo.setFrontSeqNum(upqcC2bAddDealRequest.getVoucherNum());
        // 订单金额
        userOrderInfo.setOrderAmt(upqcC2bAddDealRequest.getOrderAmt());
        // 订单币种
        userOrderInfo.setOrderCcy(upqcC2bAddDealRequest.getOrderCcy());
        // 附加信息有值
        if (upqcC2bAddDealRequest.getTransAddnInfo() != null) {
            String transAddnInfoStr = new String(Base64.decodeBase64(upqcC2bAddDealRequest.getTransAddnInfo()));
            UpqcTransAddnInfo transAddnInfo = (UpqcTransAddnInfo) convertKvStr2Bean(transAddnInfoStr.substring(1, transAddnInfoStr.length() - 1), UpqcTransAddnInfo.class);
            userOrderInfo.setGroupMchntName(transAddnInfo.getMerName());
            userOrderInfo.setGroupMchntNo(transAddnInfo.getMerId());
        }

        /* 获取用户支付金额对应的认证方式 */
        UserService userService = new UserServiceImpl();
        UserPayAuthTypeEnum userPayAuthTypeEnum = userService.getUserPayAuthType(instId, userOrderInfo.getUserId(), userOrderInfo.getOrderAmt(), LimitTypeEnum.C2B_QR.getLimitType());
        JSONObject orderExtInfo;
        if (StringUtil.isEmptyOrNull(userOrderInfo.getOrderExtraInfo())) {
            orderExtInfo = new JSONObject();
        } else {
            orderExtInfo = JSON.parseObject(userOrderInfo.getOrderExtraInfo());
        }
        rglog.debug("当前的认证方式::<{}-{}>", userPayAuthTypeEnum.getType(), userPayAuthTypeEnum.getDesc());
        orderExtInfo.put("order_auth_type", userPayAuthTypeEnum.getType());
        userOrderInfo.setOrderExtraInfo(JSON.toJSONString(orderExtInfo));

        /* 更新订单信息 */
        if (!orderService.updateOrderInfo(userOrderInfo, null, null)) {
            rglog.error("更新支付订单状态失败");
            throw new BizException(RespCodeEnum.ORDER_UPDATE_ERROR.getRespCode(), RespCodeEnum.ORDER_UPDATE_ERROR.getRespDesc());
        }

        //若为免密支付，则直接向银联发起附加信息处理结果通知
        if (UserPayAuthTypeEnum.NO_PASSWORD.equals(userPayAuthTypeEnum)) {
            rglog.debug("免密支付，直接调用BankC2bAddDealNoticeService接口响应银联!");
            //订单业务状态为初始化
            xmlTreeUtil.setXmlTreeStringValue("qrNo", userOrderInfo.getOrderUrl());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.MSG_SRC_ID, ChannelEnum.COPS.getChannelType());
            TxnInfoService txnInfoService = new TxnInfoServiceImpl();
            TxnInfo txnInfo = txnInfoService.getTxnInfo(instId, ChannelEnum.COPS.getChannelType(), AppParamConstant.DEFAULT_BIZ_CHANNEL_ID, "T00CP021", AppParamConstant.DEFAULT_BIZ_TYPE);
            C2bAddDealNoticeService c2bAddDealNoticeService = new C2bAddDealNoticeService();
            c2bAddDealNoticeService.callService(txnInfo, null, "00", upqcC2bAddDealRequest);
        }

        /* 组装应答报文 */
        BizResponse bizResponse = new BizResponse();
        UpqcC2bAddDealResponse c2BAddDealResponse = new UpqcC2bAddDealResponse();
        c2BAddDealResponse.setHeader(c2BAddDealResponse.getHeader());
        bizResponse.setResult(c2BAddDealResponse);
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        UpqcC2bAddDealResponse c2BAddDealResponse = (UpqcC2bAddDealResponse) bizResponse.getResult();
        ConvertUtil.convertInput(c2BAddDealResponse);
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        Optional<ChannelCallCfg> channelCallCfgOpt = channelCallCfgList.stream().filter(item -> item.getBizScene().equals("00")).findFirst();
        return channelCallCfgOpt.orElse(null);
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return CheckResultEnum.PASSED;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        return null;
    }
}
